# -*- coding: utf-8 -*-

import sys, os, time
import json

import requests
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QWidget, QSizePolicy, QLabel, QPushButton, QTableView, QListWidget, QListWidgetItem
from PyQt5.QtWidgets import QSlider, QHBoxLayout, QVBoxLayout, QApplication, QMainWindow, QMessageBox, QAction, QListView
from PyQt5.QtWidgets import QSpacerItem, QFileDialog, QAbstractItemView, QHeaderView, QLineEdit, QMenu
from PyQt5.QtGui import QFont, QPixmap, QIcon, QCursor, QStandardItem, QStandardItemModel
from PyQt5.QtMultimedia import QMediaPlaylist, QMediaContent
from PyQt5.QtCore import Qt, QVersionNumber, QSize, QMetaObject, QCoreApplication, QTimer, QUrl, QPoint
from PyQt5.Qt import QT_VERSION_STR

from utils.MediaPlayer import Myplayer
from utils import SongInfo, Searcher
from subWindows import AddMySongListWindow, LoginWindow

# 播放暂停标签的标志, True为暂停状态
Label_3_Clicked_Flag = True
# 初始化全局的播放器
GlobalPlayer = Myplayer()
# 音乐文件所在的根目录，写入配置文件
DirUrl = ''
# 当前播放歌曲索引
CurrentSongIndex = 0
# 音量调整按钮的状态
PushButton_Label_7_Flag = True
# 循环标签状态
Label_6_Flag = 3
# 收藏按钮状态，True表示被收藏
PushButton_Favour_State = False
# 当前歌曲的收藏状态
Current_Song_Favour_State = False
# 定义本地歌曲信息播放动态列表，存储所有的歌曲的信息的列表
# ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '文件路径', '是否被收藏', '是否最近播放']
Song_List = []
# 最近播放歌曲动态列表
# ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '文件路径']
Recent_Song_List = []
# 收藏歌曲动态列表
# ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '文件路径']
Favour_Song_List = []
# 自定义歌单歌曲动态列表
# ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '歌曲id', "歌单名称"]
Custom_Song_List = []
# 搜索到的歌曲动态列表
# ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
Search_Song_List = []


class Ui_MainWindow(object):
    QApplication.processEvents()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(950, 600)
        # 设置MainWindow的样式
        MainWindow.setWindowOpacity(1)  # 设置窗口透明度
        # 设置窗口无边框
        # MainWindow.setWindowFlags(Qt.FramelessWindowHint)
        MainWindow.setStyleSheet(".QWidget {border-image: url('./static/player_background.png');}"
                                 #".QWidget {backgrouund: transparent;}"
                                 # 所有的标签类的样式设置
                                 ".QLabel {color: white; font: 10pt;}"
                                 ".QLabel#label_11 {color: rgb(217, 247, 255, 255); font: 14pt;}"
                                 ".QLabel#label_6 {color: white; font: 18pt;}"
                                 # 所有的按钮类的样式设置
                                 ".QPushButton {padding:0 0 0 0; margin:0 0 0 0; color:grey; font: 12pt; text-align:left;}"
                                 ".QPushButton:hover {color: red;}"
                                 ".QPushButton:focus {color: red;}"
                                 ".QPushButton:pressed {background-color: rgb(127, 127, 127, 0);}"
                                 # 列表表格展示区垂直方向的表头的样式设置
                                 "QHeaderView:vertical {"
                                     "font: 12px '黑体';"
                                     "padding: 0 0 0 0;"
                                     "width: 15px;"
                                     "border: none;"
                                     "background-color: rgb(127, 127, 127, 30);"
                                     "}"
                                 "QHeaderView::section:vertical {"
                                     "background-color: rgb(127, 127, 127, 30);"
                                     "font:'黑体' 12pt;"
                                     "}"
                                 "QTableView {border: none; background-color: rgb(127, 127, 127, 30);}"
                                 # 播放进度条样式设置
                                 "QSlider::section {background-color: red;}"
                                 # "QTableView::item {border: 0; color: white; background-color: rgb(127, 127, 127, 30);}"
                                 "QListWidget{"
                                    "background-color: rgb(127, 127, 127, 0);"
                                    "padding:0 0 0 0;"
                                    "margin:0 0 0 0;"
                                    "color: grey;"
                                    "font: 10pt;"
                                    "border: 0px;"
                                    "outline: 0px"
                                    "}"
                                 "QListWidget::scroll{"
                                    "background-color: rgb(127, 127, 127, 0);"
                                    "outline: 0px"
                                    "}"
                                 "QListWidget::Item{"
                                     "background-color: rgb(127, 127, 127, 0);"
                                     "padding:5px 5px 5px 5px;"
                                     "margin:0 0 0 0;"
                                     "color: grey;"
                                     "font: 10pt;"
                                     "border: 0px;"
                                     "}"
                                 "QListWidget::Item:hover{"
                                     "background-color: rgb(127, 127, 127, 0);"
                                     "color: red;"
                                     "font: 10pt;"
                                     "}"
                                 "QListWidget::Item:focus{"
                                     "background-color: rgb(127, 127, 127, 0);"
                                     "padding:5px 5px 5px 5px;"
                                     "}"
                                 "QMessageBox::warning{"
                                     "background-color: white;"
                                     "color: black;"
                                     "}"
                                 )
        # MainWindow.setAttribute(Qt.WA_TranslucentBackground)  # 设置窗口背景透明
        # 毛玻璃特效
        # from ctypes import cdll
        # from ctypes.wintypes import HWND, DWORD
        # MainWindow.setAttribute(Qt.WA_TranslucentBackground, True)
        # self.hWnd = HWND(int(MainWindow.winId()))  # 直接HWND(self.winId())会报错
        # self.gradientColor = DWORD(0x50F2F2F2)   # 设置和亚克力效果相叠加的背景颜色
        # cdll.LoadLibrary('.\\acrylic.dll').setBlur(self.hWnd, self.gradientColor)


        # 主窗口的大小策略设置
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(16)
        sizePolicy.setVerticalStretch(9)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setMinimumSize(QSize(750, 550))

        self.verticalLayout_7 = QVBoxLayout(self.centralwidget)
        self.verticalLayout_7.setObjectName("verticalLayout_7")
        self.verticalLayout_6 = QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(1)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setSpacing(1)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_3 = QVBoxLayout()
        self.verticalLayout_3.setSpacing(10)
        self.verticalLayout_3.setObjectName("verticalLayout_3")

        # 用户登录按钮、用户登录显示文本组成的水平布局
        self.horizontalLayout_user = QHBoxLayout(self.centralwidget)
        self.horizontalLayout_user.setObjectName("horizontalLayout_user")

        # 用户登录按钮
        self.pushButton_user = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_user.sizePolicy().hasHeightForWidth())
        self.pushButton_user.setSizePolicy(sizePolicy)
        self.pushButton_user.setMinimumSize(QSize(30, 30))
        self.pushButton_user.setObjectName("pushButton_user")
        self.pushButton_user.setStyleSheet(
            "border-image: url('./static/user_avatar.jpg'); border-radius: 15px;")
        self.pushButton_user.setCursor(QCursor(Qt.PointingHandCursor))
        self.horizontalLayout_user.addWidget(self.pushButton_user)

        # 用户名称标签
        self.label_username = QLabel(self.centralwidget)
        self.label_username.setText("lawaiter")
        self.horizontalLayout_user.addWidget(self.label_username)

        # 左侧垂直布局添加用户登录按钮、用户登录显示文本组成的水平布局
        self.verticalLayout_3.addLayout(self.horizontalLayout_user)


        # 发现按钮
        self.pushButton = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setMinimumSize(QSize(136, 30))
        font = QFont()
        font.setFamily("黑体")
        font.setPointSize(12)
        self.pushButton.setFont(font)
        self.pushButton.setFlat(True)
        self.pushButton.setCursor(QCursor(Qt.PointingHandCursor))
        # 设置按钮前面的矢量小图标
        self.pushButton_pix = QIcon()
        self.pushButton_pix.addPixmap(QPixmap('./static/pushButton.png'))
        self.pushButton.setIcon(self.pushButton_pix)
        self.pushButton.setIconSize(QSize(30, 30))
        self.pushButton.setObjectName("pushButton")
        self.verticalLayout_3.addWidget(self.pushButton)

        # 我的音乐标签
        self.label_8 = QLabel(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth())
        self.label_8.setSizePolicy(sizePolicy)
        self.label_8.setMinimumSize(QSize(136, 30))
        self.font = QFont()
        self.font.setFamily("黑体")
        self.font.setPointSize(12)
        self.label_8.setFont(font)
        self.label_8.setObjectName("label_8")
        self.verticalLayout_3.addWidget(self.label_8)

        # 本地音乐按钮
        self.pushButton_3 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth())
        self.pushButton_3.setSizePolicy(sizePolicy)
        self.pushButton_3.setMinimumSize(QSize(136, 30))
        self.pushButton_3.setFont(font)
        self.pushButton_3.setFlat(True)
        self.pushButton_3.setCursor(QCursor(Qt.PointingHandCursor))
        # 设置按钮前面的矢量小图标
        self.pushButton_3_pix = QIcon()
        # .scaled(30, 30, Qt.IgnoreAspectRatio, Qt.SmoothTransformation
        self.pushButton_3_pix.addPixmap(QPixmap('./static/pushButton_3.png'))
        self.pushButton_3.setIcon(self.pushButton_3_pix)
        self.pushButton_3.setIconSize(QSize(30, 30))
        self.pushButton_3.setObjectName("pushButton_3")
        self.verticalLayout_3.addWidget(self.pushButton_3)

        # 最近播放按钮
        self.pushButton_4 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_4.sizePolicy().hasHeightForWidth())
        self.pushButton_4.setSizePolicy(sizePolicy)
        self.pushButton_4.setMinimumSize(QSize(136, 30))
        self.pushButton_4.setFont(self.font)
        self.pushButton_4.setFlat(True)
        self.pushButton_4.setCursor(QCursor(Qt.PointingHandCursor))
        # 设置按钮前面的矢量小图标
        self.pushButton_4_pix = QIcon()
        self.pushButton_4_pix.addPixmap(QPixmap('./static/pushButton_4.png'))
        self.pushButton_4.setIcon(self.pushButton_4_pix)
        self.pushButton_4.setIconSize(QSize(30, 30))
        self.pushButton_4.setObjectName("pushButton_4")
        self.verticalLayout_3.addWidget(self.pushButton_4)

        # 我的收藏按钮
        self.pushButton_5 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_5.sizePolicy().hasHeightForWidth())
        self.pushButton_5.setSizePolicy(sizePolicy)
        self.pushButton_5.setMinimumSize(QSize(136, 30))
        self.pushButton_5.setFont(self.font)
        self.pushButton_5.setFlat(True)
        self.pushButton_5.setCursor(QCursor(Qt.PointingHandCursor))
        # 设置按钮前面的矢量小图标
        self.pushButton_5_pix = QIcon()
        self.pushButton_5_pix.addPixmap(QPixmap('./static/pushButton_5.png'))
        self.pushButton_5.setIcon(self.pushButton_5_pix)
        self.pushButton_5.setIconSize(QSize(30, 30))
        self.pushButton_5.setObjectName("pushButton_5")
        self.verticalLayout_3.addWidget(self.pushButton_5)

        # 创建的歌单标签、增加创建的歌单按钮组成的水平布局
        self.horizontalLayout_label_9 = QHBoxLayout()
        self.horizontalLayout_label_9.setSpacing(2)
        self.horizontalLayout_label_9.setObjectName("horizontalLayout_label_9 ")

        # 创建的歌单标签
        self.label_9 = QLabel(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth())
        self.label_9.setSizePolicy(sizePolicy)
        self.label_9.setMinimumSize(QSize(50, 30))
        self.label_9.setFont(self.font)
        self.label_9.setObjectName("label_9")
        self.horizontalLayout_label_9.addWidget(self.label_9)

        # 创建歌单中间的水平空格弹簧
        spacerItem_label_9 = QSpacerItem(45, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_label_9.addItem(spacerItem_label_9)

        # 创建歌单按钮
        self.pushButton_label_9 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_label_9.sizePolicy().hasHeightForWidth())
        self.pushButton_label_9.setSizePolicy(sizePolicy)
        self.pushButton_label_9.setObjectName("pushButton_label_9")
        self.pushButton_label_9.setFlat(True)
        self.pushButton_label_9.setCursor(QCursor(Qt.PointingHandCursor))
        self.pushButton_label_9.setStyleSheet(
                "border-image: url('./static/pushButton_label_9.svg'); width: 20px; height: 25px;"
                "cursor: pointer;"
            )
        self.horizontalLayout_label_9.addWidget(self.pushButton_label_9)
        self.verticalLayout_3.addLayout(self.horizontalLayout_label_9)

        # 创建的歌单下面自己创建的歌单
        self.listwidget_6 = QListWidget(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.listwidget_6.sizePolicy().hasHeightForWidth())
        self.listwidget_6.setSizePolicy(sizePolicy)
        self.listwidget_6.setMinimumSize(QSize(136, 30))
        self.listwidget_6.setFont(self.font)
        # self.listwidget_6.setCursor(QCursor(Qt.PointingHandCursor))
        self.listwidget_6.setObjectName("listwidget_6")
        # 设置右侧的垂直滚动条隐藏
        self.listwidget_6.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        # 设置item中的图标的大小
        self.listwidget_6.setIconSize(QSize(20, 20))
        # 设置自定义的右键菜单
        self.listwidget_6.setContextMenuPolicy(Qt.CustomContextMenu)
        # # 循环添加项目
        # for i in range(16):
        #     a = QListWidgetItem("我的歌单" + str(i))
        #     a.setIcon(QIcon("./static/listWidgetItem.svg"))
        #     a.setTextAlignment(Qt.AlignLeft)
        #     self.listwidget_6.addItem(a)
        self.verticalLayout_3.addWidget(self.listwidget_6)

        # 左边列表纵向布局纵向空格
        self.verticalLayout_3.setStretch(0, 1)
        self.verticalLayout_3.setStretch(1, 1)
        self.verticalLayout_3.setStretch(2, 1)
        self.verticalLayout_3.setStretch(3, 1)
        self.verticalLayout_3.setStretch(4, 1)
        self.verticalLayout_3.setStretch(5, 1)
        self.verticalLayout_3.setStretch(6, 1)
        self.verticalLayout_3.setStretch(7, 10)

        # 上半部分水平布局，添加上半部分左侧的垂直布局
        self.horizontalLayout.addLayout(self.verticalLayout_3)

        # 上半部分水平布局中间水平空格
        spacerItem1 = QSpacerItem(5, 5, QSizePolicy.Fixed, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)

        # 本地歌曲标曲、空格、添加歌曲按钮组成的水平布局
        self.horizontalLayout_12 = QHBoxLayout()
        self.horizontalLayout_12.setSpacing(200)
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")

        # 本地歌曲标曲、空格、添加歌曲按钮组成的水平布局，同列表表格展示区组成的垂直布局
        self.verticalLayout_4 = QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.verticalLayout_4.setSpacing(10)

        # 本地歌曲标签
        self.label_12 = QLabel(self.centralwidget)
        self.label_12.setText("本地歌曲")
        self.label_12.setStyleSheet("color: white; font: 24pt;")
        self.font = QFont()
        self.font.setFamily("黑体")
        self.label_12.setFont(self.font)

        # 本地歌曲标签、添加歌曲按钮中间空格
        self.space_item_12 = QSpacerItem(200, 5, QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.horizontalLayout_12.addWidget(self.label_12)

        # 搜索输入框
        self.lineedit_12 = MyLineEdit(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self.lineedit_12.setMinimumSize(200, 22)
        self.lineedit_12.setStyleSheet(
                "border-radius: 10px;"
                "font: 75 10pt '黑体';"
                "background-color: rgb(255, 255, 215, 90);"
                "color: white;"
                # 不采用这种方式
                # "background-image: url('./static/lineedit_12.svg');"
                # "background-repeat: no-repeat;"
                # "background-position: right;"
            )
        # 限制输入框的最大长度是10个字符
        self.lineedit_12.setMaxLength(10)

        self.lineedit_12_image = QAction(self.lineedit_12)
        self.lineedit_12_image.setIcon(QIcon("./static/lineedit_12.svg"))
        self.lineedit_12.addAction(self.lineedit_12_image, QLineEdit.TrailingPosition)
        self.horizontalLayout_12.addWidget(self.lineedit_12)
        self.horizontalLayout_12.addItem(self.space_item_12)

        # 添加歌曲按钮
        self.pushButton_12 = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_12.sizePolicy().hasHeightForWidth())
        self.pushButton_12.setSizePolicy(sizePolicy)
        self.pushButton_12.setFlat(True)
        self.pushButton_12.setText("添加歌曲")
        self.pushButton_12.setFont(self.font)
        self.pushButton_12.setStyleSheet("color: red;")
        self.horizontalLayout_12.addWidget(self.pushButton_12)
        self.verticalLayout_4.addLayout(self.horizontalLayout_12)

        # 本地歌曲列表展示区需要绑定的数据模型
        self.model = QStandardItemModel(0, 6)  # 创造数据模型，0行，6列
        self.model.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小'])

        # 最近播放列表展示区需要绑定的数据模型
        self.recentModel = QStandardItemModel(0, 7)  # 创造数据模型，0行，7列
        self.recentModel.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏'])

        # 收藏歌曲列表展示区需要绑定的数据模型
        self.favourModel = QStandardItemModel(0, 6)  # 创造数据模型，0行，6列
        self.favourModel.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小'])

        # 自定义歌曲列表展示区需要绑定的数据模型
        self.customSongModel = QStandardItemModel(0, 7)  # 创造数据模型，0行，7列
        self.customSongModel.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏'])

        # 搜索的歌曲列表展示区需要绑定的数据模型
        self.searchSongModel = QStandardItemModel(0, 6)  # 创造数据模型，0行，6列
        self.searchSongModel.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏'])

        # 本地歌曲列表表格展示区
        self.tableView = MyTableView(self.centralwidget)
        self.tableView.setObjectName("tableView")
        # 将数据模型绑定到列表表格上
        self.tableView.setModel(self.model)
        # 设置名称列宽
        self.tableView.setColumnWidth(0, 10)
        # 设置播放按钮列框
        self.tableView.setColumnWidth(1, 200)
        # 设置歌手列宽
        self.tableView.setColumnWidth(2, 200)
        # 设置专辑列宽
        self.tableView.setColumnWidth(3, 158)
        # 设置时长列宽
        self.tableView.setColumnWidth(4, 200)
        # 设置文件大小列宽
        self.tableView.setColumnWidth(5, 158)
        # 设置默认播放的歌曲索引值
        self.tableView.selectRow(GlobalPlayer.playList.currentIndex())

        self.verticalLayout_4.addWidget(self.tableView)
        self.verticalLayout_4.setStretch(0, 1)
        self.verticalLayout_4.setStretch(1, 4)

        # 上半部分水平布局
        self.horizontalLayout.addLayout(self.verticalLayout_4)
        self.horizontalLayout.setStretch(0, 20)
        self.horizontalLayout.setStretch(1, 1)
        self.horizontalLayout.setStretch(2, 140)
        self.verticalLayout.addLayout(self.horizontalLayout)

        # 上半部分水平布局和纵向空格形成垂直布局
        spacerItem2 = QSpacerItem(301, 13, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem2)
        self.verticalLayout.setStretch(0, 60)
        self.verticalLayout.setStretch(1, 1)
        self.verticalLayout_6.addLayout(self.verticalLayout)
        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")

        # 正在播放歌曲图片标签
        self.pushButton_label = QPushButton(self.centralwidget)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton_label.sizePolicy().hasHeightForWidth())
        self.pushButton_label.setSizePolicy(sizePolicy)
        self.pushButton_label.setFlat(True)
        self.font.setPointSize(12)
        self.pushButton_label.setFont(self.font)
        # 显示图片, 按指定路径找到图片，注意路径必须用单引号包围，同时设置长宽
        self.pushButton_label.setStyleSheet(
                "border-image: url('./static/defalut_playing_image.jpg'); width: 70px; height: 70px;"
            )
        self.pushButton_label.setObjectName("pushButton_label")
        self.horizontalLayout_3.addWidget(self.pushButton_label)

        # 后退标签
        self.label_2 = MyLabelBack(self.centralwidget)
        self.label_2.setFont(self.font)
        # 在label上显示图片, 按指定路径找到图片，注意路径必须用双引号包围，不能用单引号
        self.label_2_pix = QPixmap("./static/label_2.svg").scaled(30, 30)
        self.label_2.setPixmap(self.label_2_pix)
        # 让图片自适应label大小
        # self.label_2.setScaledContents(True)
        # self.label_2.setStyleSheet("border-image: url('./static/label_2.svg');")
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_3.addWidget(self.label_2)

        # 播放标签
        self.label_3 = MyLabelPlayStop(self.centralwidget)
        self.label_3.setFont(self.font)
        # 在label上显示图片, 按指定路径找到图片，注意路径必须用双引号包围，不能用单引号
        self.label_3_pix = QPixmap("./static/label_3_play.svg").scaled(40, 50)
        self.label_3.setPixmap(self.label_3_pix)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_3.addWidget(self.label_3)

        # 前进标签
        self.label_4 = MyLabelGo(self.centralwidget)
        self.label_4.setFont(self.font)
        # 在label上显示图片, 按指定路径找到图片，注意路径必须用双引号包围，不能用单引号
        self.label_4_pix = QPixmap("./static/label_4.svg").scaled(30, 30)
        self.label_4.setPixmap(self.label_4_pix)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_3.addWidget(self.label_4)

        # 当前播放的歌曲名称歌手信息标签、播放进度条水平布局组成的垂直布局
        self.verticalLayout_5 = QVBoxLayout()
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.verticalLayout_5.setSpacing(5)
        self.verticalLayout_5.setStretch(0, 1)
        self.verticalLayout_5.setStretch(1, 1)

        # 当前播放歌曲名称和歌手信息标签
        self.label_11 = QLabel(self.centralwidget)
        self.label_11.setFont(self.font)
        self.label_11.setText("无歌曲歌手")
        self.label_11.setObjectName("label_11")
        self.verticalLayout_5.addWidget(self.label_11)

        # 播放进度条、收藏、循环、音量的水平布局
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout_2.setSpacing(10)

        # 播放进度条
        self.horizontalSlider = QSlider(self.centralwidget)
        self.horizontalSlider.setOrientation(Qt.Horizontal)
        self.horizontalSlider.setObjectName("horizontalSlider")
        self.horizontalLayout_2.addWidget(self.horizontalSlider)

        # 播放时间标签
        self.label_10 = QLabel(self.centralwidget)
        font = QFont()
        font.setFamily("黑体")
        font.setPointSize(12)
        self.label_10.setText("00:00/00:00")
        self.label_10.setObjectName("label_10")
        self.horizontalLayout_2.addWidget(self.label_10)

        # 收藏标签
        self.pushbutton_label_5 = QPushButton(self.centralwidget)
        # 显示图片, 按指定路径找到图片
        self.pushbutton_label_5.setStyleSheet(
            "border-image: url('./static/pushButton_label_5_unsaved.svg'); width: 25px; height: 25px;")
        self.pushbutton_label_5.setObjectName("label_5")
        self.horizontalLayout_2.addWidget(self.pushbutton_label_5)

        # 循环标签
        global Label_6_Flag
        self.label_6 = MyLabel6(self.centralwidget)
        self.label_6.setStyleSheet("font: '黑体' 22pt; color: white;")
        self.label_6.setText("循环")
        Label_6_Flag = 3
        GlobalPlayer.playList.setPlaybackMode(Label_6_Flag)
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_2.addWidget(self.label_6)

        # 音量调整按钮
        self.pushbutton_label_7 = QPushButton(self.centralwidget)
        self.pushbutton_label_7.setFont(self.font)
        # 显示图片, 按指定路径找到图片
        self.pushbutton_label_7.setStyleSheet(
            "border-image: url('./static/pushButton_label_7.svg'); width: 20px; height: 20px;")
        self.pushbutton_label_7.setObjectName("pushbutton_label_7")
        self.horizontalLayout_2.addWidget(self.pushbutton_label_7)

        self.verticalLayout_5.addLayout(self.horizontalLayout_2)

        # 底部正在播放图片、后退、播放、前进、进度条和动态效果展示区垂直布局构成的水平布局
        self.horizontalLayout_3.addLayout(self.verticalLayout_5)
        self.horizontalLayout_3.setStretch(0, 2)
        self.horizontalLayout_3.setStretch(1, 1)
        self.horizontalLayout_3.setStretch(2, 1)
        self.horizontalLayout_3.setStretch(3, 1)
        self.horizontalLayout_3.setStretch(4, 16)

        # 上半部分和底部构成的垂直布局
        self.verticalLayout_6.addLayout(self.horizontalLayout_3)
        self.verticalLayout_6.setStretch(0, 100)
        self.verticalLayout_6.setStretch(1, 10)
        self.verticalLayout_7.addLayout(self.verticalLayout_6)
        MainWindow.setCentralWidget(self.centralwidget)

        # 刷新播放列表表格数据
        self.setLocalTableViewModel()

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)

        # 初始化计时器
        self.timer = QTimer()

        # 所有的信号与槽方法
        self.signalAction()

        QApplication.processEvents()

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "音乐播放器"))
        self.pushButton.setText(_translate("MainWindow", " 发现音乐"))
        self.label_8.setText(_translate("MainWindow", "我的音乐"))
        self.pushButton_3.setText(_translate("MainWindow", " 本地音乐"))
        self.pushButton_4.setText(_translate("MainWindow", " 最近播放"))
        self.pushButton_5.setText(_translate("MainWindow", " 我的收藏"))
        self.label_9.setText(_translate("MainWindow", "创建的歌单"))
        # self.label.setText(_translate("MainWindow", "图片"))
        # self.label_2.setText(_translate("MainWindow", "后退"))
        # self.label_3.setText(_translate("MainWindow", "播放"))
        # self.label_4.setText(_translate("MainWindow", "前进"))
        # self.pushbutton_label_5.setText(_translate("MainWindow", "收藏"))
        # self.label_6.setText(_translate("MainWindow", "循环"))
        # self.label_7.setText(_translate("MainWindow", "音量"))

    def currentPlayListIndex(self):

        """
        功能函数
        依据界面的不同，获取不同界面下选中的歌曲，在歌曲信息列表中的位置索引值
        """

        global GlobalPlayer, Song_List, Recent_Song_List, Favour_Song_List
        # 如果是在搜索结果界面的话
        if self.label_12.text() == "搜索歌曲":
            pass
        else:
            if self.label_12.text() == "本地歌曲":
                print("进入0")
                self.name = self.model.item(self.tableView.currentIndex().row(), 0).text()
                print(self.name)
            elif self.label_12.text() == "最近播放":
                print("进入1")
                self.name = self.recentModel.item(self.tableView.currentIndex().row(), 0).text()
                print(self.name)
            elif self.label_12.text() == "我的收藏":
                print("进入2")
                self.name = self.favourModel.item(self.tableView.currentIndex().row(), 0).text()
            else:
                print("进入3")
                self.name = self.customSongModel.item(self.tableView.currentIndex().row(), 0).text()
            for i in Song_List:
                if i[0] == self.name:
                    print("选中的i", i)
                    return Song_List.index(i)

    def saveSongDir(self):

        """
        槽函数
        打开问价夹选择对话框，保存歌曲所在路径在配置文件playSetting.ini之中
        :return: 播放器的歌曲查找路径
        """

        # 声明音乐文件所在根目录，这个变量等同于mediaPlayer中MyPlayer类中的songsDir
        global DirUrl
        # 打开文件夹对话框，循环显示
        filedialog = QFileDialog()
        filedialog.setFileMode(QFileDialog.Directory)
        filedialog.show()
        filedialog.exec_()
        try:
            # 保存选择的文件夹目录
            DirUrl = filedialog.selectedFiles()[0]
            print(DirUrl)
            # 把该文件夹目录写入json配置文件
            if os.path.exists('./conf'):
                with open('./conf/playSetting.json', 'w') as f:
                    json.dump({'DIR_URL': DirUrl}, f)
            else:
                os.mkdir('./conf')
                with open('./conf/playSetting.json', 'w') as f:
                    json.dump({'DIR_URL': DirUrl}, f)
        except:
            print(os.getcwd())
            DirUrl = './'
        # 让播放器中的音乐目录等于选择的目录
        GlobalPlayer.songsDir = DirUrl
        # 重新刷新播放器的播放列表
        GlobalPlayer.addSongsToPlaylist()
        # 刷新列表表格显示新的播放器的播放列表
        self.setLocalTableViewModel()

    def clickGetSongInfo(self):

        """
        槽函数
        点击列表表格某一行后，将选中的歌曲装载到播放器的播放列表中，同时显示相关信息
        """
        global GlobalPlayer, Search_Song_List
        if self.label_12.text() == "搜索歌曲":
            # Search_Song_List =  ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
            url =  Search_Song_List[self.tableView.currentIndex().row()][6]
            # 获取对应歌曲id的url链接
            self.searchSongUrl = requests.get("http://122.51.226.175:3000/song/url?id="+ str(url)).json()['data'][0]['url']
            # 将该歌曲装载至全局播放器
            GlobalPlayer.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.searchSongUrl)))
            # self.searchSongModel = (['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏'])
            self.currentSongTitle = self.searchSongModel.item(self.tableView.currentIndex().row(), 0).text()
            self.currentSongArtist = self.searchSongModel.item(self.tableView.currentIndex().row(), 2).text()
            self.timeLength = self.searchSongModel.item(self.tableView.currentIndex().row(), 4).text()
        # 如果是在本地歌曲搜索界面的话，就装载本地歌曲列表
        else:
            # 获取但当前选中的行的歌曲的索引值
            self.currentSongIndex = self.currentPlayListIndex()
            # self.currentSongIndex = self.tableView.currentIndex().row()
            # 获取到不同界面下该索引值对应的相关的单元格的内容，歌曲名称、歌手和时间长度
            if self.label_12.text() == "本地歌曲":
                self.currentSongTitle = self.model.item(self.tableView.currentIndex().row(), 0).text()
                self.currentSongArtist = self.model.item(self.tableView.currentIndex().row(), 2).text()
                self.timeLength = self.model.item(self.tableView.currentIndex().row(), 4).text()
            elif self.label_12.text() == "最近播放":
                self.currentSongTitle = self.recentModel.item(self.tableView.currentIndex().row(), 0).text()
                print(self.currentSongTitle)
                self.currentSongArtist = self.recentModel.item(self.tableView.currentIndex().row(), 2).text()
                print(self.currentSongArtist)
                self.timeLength = self.recentModel.item(self.tableView.currentIndex().row(), 4).text()
                print(self.timeLength)
            elif self.label_12.text() == "我的收藏":
                self.currentSongTitle = self.favourModel.item(self.tableView.currentIndex().row(), 0).text()
                self.currentSongArtist = self.favourModel.item(self.tableView.currentIndex().row(), 2).text()
                self.timeLength = self.favourModel.item(self.tableView.currentIndex().row(), 4).text()

            # 将全局播放器中的播放列表的当前播放曲目设置为选中的歌曲
            GlobalPlayer.playList.setCurrentIndex(self.currentSongIndex)
            # 获取全局播放器中播放列表中当前播放曲目的路径
            self.currentSongPath = GlobalPlayer.player.currentMedia().canonicalUrl().path()[1:]
            # 找到当前全局播放器中播放列表对应的收藏状态并显示
            for i in Song_List:
                if i[6] == self.currentSongPath:
                    if i[7] == True:
                        self.pushbutton_label_5.setStyleSheet(
                            "border-image: url('./static/pushButton_label_5_saved.svg'); width: 25px; height: 25px;")
                    else:
                        self.pushbutton_label_5.setStyleSheet(
                            "border-image: url('./static/pushButton_label_5_unsaved.svg'); width: 25px; height: 25px;")
            # 找到该歌曲对应的专辑图片路径和图片文件路径，注意这里必须是使用png格式，QpushButton对jpg格式支持不好
            self.currentSongAlbumImagePath = os.path.dirname(self.currentSongPath) + '/album'
            self.currentSongAlbumImage = self.currentSongAlbumImagePath + '/' + self.currentSongTitle + '.png'
            # 同时如果有专辑图片的话，更新专辑图片显示，否则显示默认图片
            if os.path.exists(self.currentSongAlbumImage):
                albumImageStyleString = "border-image: url('" + self.currentSongAlbumImage + "'); width: 70px; height: 70px;"
                self.pushButton_label.setStyleSheet(albumImageStyleString)
            else:
                self.pushButton_label.setStyleSheet(
                    "border-image: url('./static/defalut_playing_image.jpg'); width:70px; height: 70px;")
        # 总的播放时间，分、秒
        self.label_10_duration_min = str(self.timeLength.split(":", 1)[0])
        self.label_10_duration_sec = str(self.timeLength.split(":", 1)[1])
        self.currentSongLength = int(self.label_10_duration_min) * 60 + int(self.label_10_duration_sec)
        # 拼接当前播放曲目和歌手的信息字符串
        self.currentSongString = self.currentSongTitle[:20] + '—' + self.currentSongArtist
        # 更新当前正在播放的曲目和歌手的信息
        self.label_11.setText(self.currentSongString)
        # 设置播放器的播放进度条，最小值和最大值
        self.horizontalSlider.setMinimum(0)
        self.horizontalSlider.setMaximum(self.currentSongLength * 1000)
        print("click", self.horizontalSlider.maximum())
        # 设置播放时间标签
        # 当前的播放时间，分、秒
        self.label_10_postion = GlobalPlayer.player.position() // 1000 * 1000
        self.label_10_duration = self.currentSongLength
        self.label_10.setText(
            time.strftime('%M:%S', time.localtime(self.label_10_postion)) + "/"
            + time.strftime('%M:%S', time.localtime(self.label_10_duration))
        )

    def changeStatus(self):

        """
        槽函数
        全局播放器中播放列表的当前播放歌曲一改变，就显示对应的歌曲名称和专辑图片
        """

        global GlobalPlayer, Recent_Song_List, Song_List, Favour_Song_List, PushButton_Favour_State, Current_Song_Favour_State
        if self.label_12.text() == "搜索歌曲":
            # Search_Song_List =  ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
            info = Search_Song_List[self.tableView.currentIndex().row()]
            self.currentSongTitle = info[0]
            self.currentSongArtist = info[2]
            path = info[6]
        else:
            # 获取但当前选中的行的歌曲的索引值
            self.currentSongIndex = self.currentPlayListIndex()
            # 将全局播放器中的播放列表的当前播放曲目设置为选中的歌曲
            GlobalPlayer.playList.setCurrentIndex(self.currentSongIndex)
            # self.currentSongIndex = GlobalPlayer.playList.currentIndex()
            # CurrentSongIndex = self.currentSongIndex
            # 获取到列表表格该索引值对应的相关的单元格的内容
            path = GlobalPlayer.player.currentMedia().canonicalUrl().path()[1:]
            if path[-3:] == 'mp3' or path[-3:] == 'MP3':
                info = SongInfo.GetMp3Info(path)
                self.currentSongTitle = info.title
                self.currentSongArtist = info.artist
            elif path[-4:] == 'FLAC' or path[-4:] == 'flac':
                info = SongInfo.GetFlacInfo(path)
                self.currentSongTitle = info.title
                self.currentSongArtist = info.artist
            else:
                info = None
            # 获取全局播放器中播放列表中当前播放曲目的路径
            self.currentSongPath = GlobalPlayer.player.currentMedia().canonicalUrl().path()[1:]
            # 找到该歌曲对应的专辑图片路径和图片文件路径，注意这里必须是使用png格式，QpushButton对jpg格式支持不好
            self.currentSongAlbumImagePath = os.path.dirname(self.currentSongPath) + '/album'
            self.currentSongAlbumImage = self.currentSongAlbumImagePath + '/' + self.currentSongTitle + '.png'
            # 同时如果有专辑图片的话，更新专辑图片显示，否则显示默认图片
            if os.path.exists(self.currentSongAlbumImage):
                albumImageStyleString = "border-image: url('" + self.currentSongAlbumImage + "'); width: 70px; height: 70px;"
                self.pushButton_label.setStyleSheet(albumImageStyleString)
            else:
                self.pushButton_label.setStyleSheet(
                    "border-image: url('./static/defalut_playing_image.jpg'); width: 70px; height: 70px;")
            # 更新播放进度条的设置
            self.horizontalSlider.setMinimum(0)
            self.horizontalSlider.setMaximum(GlobalPlayer.player.duration() // 1000 * 1000)
            # 如果全局播放器处于播放状态，那就把当前播放的歌曲写入全局最近播放歌曲列表
            if Label_3_Clicked_Flag == False:
                # 当前该歌曲的收藏标记
                for i in Recent_Song_List:
                    if i[7] == path:
                        Current_Song_Favour_State = i[6]
                        Recent_Song_List.remove(i)
                # 最后一位代表是否是收藏歌曲，默认为0，不收藏
                # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '文件路径'], 其中文件路径不展示
                Recent_Song_List.append([
                    self.currentSongTitle, '', self.currentSongArtist, info.album, info.length, info.getSize(path),
                    Current_Song_Favour_State, path
                ])
                Current_Song_Favour_State = False
        try:
            # 拼接当前播放曲目和歌手的信息字符串
            self.currentSongString = self.currentSongTitle[:20] + '—' + self.currentSongArtist
            # 更新当前正在播放的曲目和歌手的信息
            self.label_11.setText(self.currentSongString)
        except:
            self.currentSongString = '无歌曲'
            self.label_11.setText(self.currentSongString)
            self.pushButton_label.setStyleSheet(
                "border-image: url('./static/defalut_playing_image.jpg'); width: 70px; height: 70px;")
        print("recent", Recent_Song_List)
    # TODO 播放后将搜索到的歌曲播放的，写入SONGLIst，最近播放列表，收藏的要添加到收藏列表
    # TODO 完善播放在线歌曲获得歌曲图片，或者专辑图片的方法
    def doubleClickedToPlay(self):

        """
        槽函数
        双击列表表格某一行后，播放对应的歌曲
        """

        global GlobalPlayer, Label_3_Clicked_Flag
        self.label_3_pix = QPixmap("./static/label_3_stop.svg").scaled(40, 50)
        self.label_3.setPixmap(self.label_3_pix)
        Label_3_Clicked_Flag = False
        if self.label_12.text() == "搜索歌曲":
            # Search_Song_List =  ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
            url = Search_Song_List[self.tableView.currentIndex().row()][6]
            # 获取对应歌曲id的url链接
            res = requests.get("http://122.51.226.175:3000/song/url?id=" + str(url)).json()['data'][0]
            self.searchSongUrl = res['url']
            print("self.searchSongUrl=======", self.searchSongUrl)
            # 将该歌曲装载至全局播放器
            GlobalPlayer.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.searchSongUrl)))
            # self.searchSongModel = (['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏'])
            self.currentSongTitle = self.searchSongModel.item(self.tableView.currentIndex().row(), 0).text()
            self.currentSongArtist = self.searchSongModel.item(self.tableView.currentIndex().row(), 2).text()
            self.timeLength = self.searchSongModel.item(self.tableView.currentIndex().row(), 4).text()
            # 设置播放器的播放进度条，最小值和最大值
            self.horizontalSlider.setMinimum(0)
            print("res============", res)
            print("res[size]================", res['size'])
            print("res[br]================", res['br'])
            try:
                self.horizontalSlider.setMaximum(int(str(res['size'] / res['br'] * 8 * 1000)[:6]))
            except:
                self.horizontalSlider.setMaximum(100)
            self.horizontalSlider.setValue(0)
        else:
            # 获取但当前选中的行的歌曲的索引值
            self.currentSongIndex = self.currentPlayListIndex()
            # self.currentSongIndex = self.tableView.currentIndex().row()
            GlobalPlayer.playList.setCurrentIndex(self.currentSongIndex)

            # 设置播放器的播放进度条，最小值和最大值
            self.horizontalSlider.setMinimum(0)
            self.horizontalSlider.setMaximum(GlobalPlayer.player.duration() // 1000 * 1000)
        # 设置播放时间标签
        self.label_10_postion = GlobalPlayer.player.position() // 1000 * 1000
        print(" GlobalPlayer.player.duration()========",  GlobalPlayer.player.duration())
        self.label_10_duration = GlobalPlayer.player.duration() // 1000 * 1000
        self.label_10.setText(
            time.strftime('%M:%S', time.localtime(self.label_10_postion)) + "/"
            + time.strftime('%M:%S', time.localtime(self.label_10_duration))
        )
        print("doubleclick", self.horizontalSlider.maximum())
        # 初始化计时器
        self.timer.start(1000)
        GlobalPlayer.player.play()

    def tableViewRowSelected(self):

        """
        槽函数
        将列表表格选中行设置为当前的播放列表中的歌曲索引
        """

        global GlobalPlayer, Recent_Song_List, Favour_Song_List, PushButton_Favour_State
        if self.label_12.text() == "搜索歌曲":
            pass
        else:
            self.tableView.selectRow(self.tableView.currentIndex().row())
            # 找到当前全局播放器中播放列表对应的收藏状态并显示
            for i in Song_List:
                if i[6] == self.currentSongPath:
                    if i[7] == True:
                        self.pushbutton_label_5.setStyleSheet(
                            "border-image: url('./static/pushButton_label_5_saved.svg'); width: 25px; height: 25px;")
                    else:
                        self.pushbutton_label_5.setStyleSheet(
                            "border-image: url('./static/pushButton_label_5_unsaved.svg'); width: 25px; height: 25px;")

    def saveFavourSong(self):

        """
        槽函数
        点击收藏按钮，收藏当前播放的歌曲
        """

        global GlobalPlayer, PushButton_Favour_State, Current_Song_Favour_State, Favour_Song_List, Recent_Song_List

        if PushButton_Favour_State == False:
            PushButton_Favour_State = True
            self.pushbutton_label_5.setStyleSheet(
                "border-image: url('./static/pushButton_label_5_saved.svg'); width: 25px; height: 25px;")
            path = GlobalPlayer.player.currentMedia().canonicalUrl().path()[1:]
            # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '文件路径', '是否被收藏', '是否最近播放']
            # 在歌曲信息列表中找到当前播放器歌曲，并设置为收藏
            for i in Song_List:
                if i[6] == path:
                    if i[7] == False:
                        i[7] = True
                        # 在收藏歌曲列表里面找到这首歌曲，重新收藏
                        for song in Favour_Song_List:
                            if song[7] == path:
                                Favour_Song_List.remove(song)
                        Favour_Song_List.append([i[0], i[1], i[2], i[3], i[4], i[5], i[7], i[6]])
            # 在最近播放列表里面找到歌曲，设置为收藏
            for song2 in Recent_Song_List:
                # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '文件路径']
                if song2[7] == path:
                    song2[6] = True
            print("当前的喜欢列表", Favour_Song_List)
        else:
            PushButton_Favour_State = False
            self.pushbutton_label_5.setStyleSheet(
                "border-image: url('./static/pushButton_label_5_unsaved.svg'); width: 25px; height: 25px;")
            path = GlobalPlayer.player.currentMedia().canonicalUrl().path()[1:]
            # 在歌曲信息列表里面找到当前播放器歌曲，并取消收藏
            for i in Song_List:
                if i[6] == path:
                    if i[7] == True:
                        i[7] = False
                        # 在收藏播放列表里面找到这首歌曲，并移除
                        for song in Favour_Song_List:
                            if song[7] == path:
                                Favour_Song_List.remove(song)
            # 在最近播放列表中找到该歌曲，并设置为不收藏
            for song2 in Recent_Song_List:
                # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '文件路径']
                if song2[7] == path:
                    song2[6] = False
            print("当前的喜欢列表", Favour_Song_List)

    def saveRecentSong(self):

        """
        槽函数
        将当前处于播放状态的歌曲写入最近播放列表
        """

        self.changeStatus()

    def sliderMove(self):

        """
        槽函数
        拖动播放进度条的前进到对应的歌曲播放时间
        """

        global GlobalPlayer
        GlobalPlayer.player.setPosition(self.horizontalSlider.value())
        print("setPosition", self.horizontalSlider.value())

    def playerTimer(self):

        """
        槽函数
        播放进度条的滑块、播放时间标签显示自动随着音乐播放更新
        """

        global GlobalPlayer
        self.horizontalSlider.setMinimum(0)
        self.horizontalSlider.setMaximum(GlobalPlayer.player.duration() // 1000 * 1000)
        self.horizontalSlider.setValue(self.horizontalSlider.value() + 1000)
        print("value", self.horizontalSlider.value())
        self.label_10.setText(
            time.strftime('%M:%S', time.localtime(GlobalPlayer.player.position() // 1000)) + "/"
            + time.strftime('%M:%S', time.localtime(GlobalPlayer.player.duration() // 1000))
        )
        # 进度条满了之后回零
        if GlobalPlayer.player.duration() // 1000 * 1000 == self.horizontalSlider.value():
            self.horizontalSlider.setValue(0)

    def timerStatus(self):

        """
        槽函数
        判断全局播放器当前的状态，如果是播放状态的话，就启动计时器，反之相反
        """

        if Label_3_Clicked_Flag == False:
            self.timer.start(1000)
        else:
            self.timer.stop()

    # TODO 这个功能目前还有问题，不能随着系统音量调整进行调整
    def volChangeAction(self):

        """
        槽函数
        点击音量按钮，出现音量调整的界面
        """

        global GlobalPlayer
        global PushButton_Label_7_Flag
        if PushButton_Label_7_Flag:
            self.volChangeWindow = Ui_VolChange()
            self.volChangeWindow.setParent(self.centralwidget)
            self.volChangeWindow.setGeometry(self.pushbutton_label_7.pos().x() - 10,
                                             self.pushbutton_label_7.pos().y() - 90, 40, 100)
            self.volChangeWindow.setStyleSheet("color: white;background-color: rgb(127, 127, 127, 0);")
            PushButton_Label_7_Flag = False
            self.volChangeWindow.vol_slider.setMaximum(100)
            self.volChangeWindow.vol_slider.setMinimum(0)
            self.volChangeWindow.vol_slider.resize(self.volChangeWindow.width() / 12,
                                                   self.volChangeWindow.height() * 3 / 5)
            self.volChangeWindow.vol_slider.move(
                (self.volChangeWindow.width() - self.volChangeWindow.vol_slider.width()) / 2,
                (self.volChangeWindow.height() - self.volChangeWindow.vol_slider.height()) * 0.2 / 2)
            # 设置步长
            self.volChangeWindow.vol_slider.setSingleStep(1)
            # 设置翻页步长，使用PageUp PageDown
            self.volChangeWindow.vol_slider.setPageStep(5)
            self.volChangeWindow.vol_slider.setTracking(True)
            self.volChangeWindow.vol_slider.setOrientation(Qt.Vertical)
            self.volChangeWindow.vol_slider.setTickPosition(QSlider.TicksBothSides)
            # self.volChangeWindow.vol_slider.setTickInterval(5)
            # 设置翻页步长，也会顺带调整刻度线密度
            # self.volChangeWindow.vol_slider.setPageStep(5)
            self.volChangeWindow.vol_slider.valueChanged.connect(self.volChange)
            self.volChangeWindow.show()
        else:
            PushButton_Label_7_Flag = True
            self.volChangeWindow.hide()

    def volChange(self):

        """
        槽函数
        音量滑块调整，全局播放器音量就跟着调整，信号放在volChangeAction槽函数中
        """

        global GlobalPlayer
        GlobalPlayer.player.setVolume(self.volChangeWindow.vol_slider.value())

    def setLocalTableViewModel(self):

        """
        功能函数
        将本地歌曲数据模型model设置在播放列表tableView上
        """

        self.model.clear()
        self.model.setHorizontalHeaderLabels(['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小'])
        global GlobalPlayer, Song_List
        # 如果播放列表中有音乐文件的话，就循环添加到列表表格里面
        for index in range(GlobalPlayer.playList.mediaCount()):
            print(index)
            # 获取歌曲文件的绝对路径，也就是含歌曲文件本身的URL路径
            path = GlobalPlayer.playList.media(index).canonicalUrl().path()[1:]
            if path[-3:] == 'mp3' or path[-3:] == 'MP3':
                info = SongInfo.GetMp3Info(path)
                self.model.appendRow([
                    QStandardItem(info.title),
                    QStandardItem(),
                    QStandardItem(info.artist),
                    QStandardItem(info.album),
                    QStandardItem(info.length),
                    QStandardItem(info.size),
                ])
                # 同时读取MP3文件中的专辑图片，并保存在./album文件夹
                info.getAlbumImage(path)
                # 将所有信息同步存在歌曲信息列表中
                Song_List.append([info.title, '', info.artist, info.album, info.length, info.size, path, False, False])
            elif path[-4:] == 'FLAC' or path[-4:] == 'flac':
                info = SongInfo.GetFlacInfo(path)
                self.model.appendRow([
                    QStandardItem(info.title),
                    QStandardItem(),
                    QStandardItem(info.artist),
                    QStandardItem(info.album),
                    QStandardItem(info.length),
                    QStandardItem(info.size),
                ])
                Song_List.append([info.title, '', info.artist, info.album, info.length, info.size, path, False, False])
                # 读取FLAC文件中的专辑图片cover.jpg，并保存在./album文件夹
                info.getAlbumImage(path)
            else:
                # 否则就清空数据模型
                self.model.clear()
        # 编历循环，所有的单元格数据居中
        for row in range(GlobalPlayer.playList.mediaCount()):
            for column in range(6):
                self.model.item(row, column).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                self.model.item(row, column).setFont(QFont("微软雅黑", 8))
        # 将数据模型绑定到列表表格里面显示
        self.tableView.setModel(self.model)
        try:
            # 设置默认显示的歌曲和歌手标签
            self.label_11.setText(self.model.item(0, 0).text() + "—" + self.model.item(0, 3).text())
            # 默认的歌曲所在行被选中
            self.tableView.selectRow(0)
        except:
            # 没有歌曲的话就显示无光驱
            self.label_11.setText("无歌曲")
        self.pushButton_3.setFocus()

    def setRecentTableViewModel(self):

        """
        功能函数
        将最近播放列表数据模型recentModel设置在播放列表tableView上
        """

        global Recent_Song_List
        # 清空已经有的最近播放列表数据模型
        self.recentModel.clear()

        # 装载最近播放的歌曲列表数据模型
        for i in Recent_Song_List:
            self.recentModel.appendRow([
                QStandardItem(i[0]),
                QStandardItem(i[1]),
                QStandardItem(i[2]),
                QStandardItem(i[3]),
                QStandardItem(i[4]),
                QStandardItem(i[5]),
                # 必须转换成string才能显示
                QStandardItem(str(i[6])),
            ])
        # 编历循环，所有的单元格数据居中
        try:
            for row in range(len(Recent_Song_List)):
                for column in range(7):
                    self.recentModel.item(row, column).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                    self.recentModel.item(row, column).setFont(QFont("微软雅黑", 8))
        except:
            pass
        finally:
            self.tableView.setModel(self.recentModel)
            QApplication.processEvents()
        # 槽与信号，双击最近播放列表播放音乐
        self.tableView.doubleClicked.connect(self.doubleClickedToPlay)

    def setFavourTableViewModel(self):

        """
        功能函数
        将收藏的歌曲列表数据模型favourModel设置在播放列表tableView上
        """

        # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '文件路径']
        global Favour_Song_List
        # 清空已经有的最近播放列表数据模型

        self.favourModel.clear()

        # 装载最近播放的歌曲列表数据模型
        for i in Favour_Song_List:
            print("set", Favour_Song_List)
            # favour_model ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小']
            if i[6] == True:
                self.favourModel.appendRow([
                    QStandardItem(i[0]),
                    QStandardItem(i[1]),
                    QStandardItem(i[2]),
                    QStandardItem(i[3]),
                    QStandardItem(i[4]),
                    QStandardItem(i[5]),
                ])
        # 编历循环，favourModel没有数据的话，直接显示空列表
        if self.favourModel.rowCount() == 0:
            self.tableView.setModel(self.favourModel)
        else:
            # favourModel有数据的话再遍历单元格显示居中，否则会报错
            for row in range(len(Favour_Song_List)):
                for column in range(5):
                    self.favourModel.item(row, column).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                    self.favourModel.item(row, column).setFont(QFont("微软雅黑", 8))
            self.tableView.setModel(self.favourModel)
        QApplication.processEvents()
        # 槽与信号，双击最近播放列表播放音乐
        self.tableView.doubleClicked.connect(self.doubleClickedToPlay)

    def setItemCustomTableViewModel(self):

        """
        功能函数
        将自定义的歌单歌曲列表数据模型customSongModel，按照不同的歌单分类设置在播放列表tableView上
        """

        # 自定义歌单歌曲动态列表
        # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏', '歌曲id', "歌单名称"]
        global Custom_Song_List
        # .customSongModel = ['歌曲', '播放按钮', '歌手', '专辑', '时长', '文件大小', '收藏']
        self.customSongModel.clear()
        self.customSongListName = self.listwidget_6.item(self.listwidget_6.currentRow()).text()
        for i in Custom_Song_List:
            if i[7] == self.customSongListName:
                self.customSongModel.appendRow([
                    QStandardItem(i[0]),
                    QStandardItem(i[1]),
                    QStandardItem(i[2]),
                    QStandardItem(i[3]),
                    QStandardItem(i[4]),
                    QStandardItem(i[5]),
                    QStandardItem(i[6]),
                ])
        # 编历循环，customSongModel没有数据的话，直接显示空列表
        if self.customSongModel.rowCount() == 0:
            self.tableView.setModel(self.customSongModel)
        else:
            # customSongModel有数据的话再遍历单元格显示居中，否则会报错
            for row in range(len([i for i in Favour_Song_List if i[7] == self.customSongListName])):
                for column in range(7):
                    self.customSongModel.item(row, column).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                    self.customSongModel.item(row, column).setFont(QFont("微软雅黑", 8))
            self.tableView.setModel(self.customSongModel)
        QApplication.processEvents()
        # 槽与信号，双击最近播放列表播放音乐
        # self.tableView.doubleClicked.connect(self.doubleClickedToPlay)
        pass

    def setSearchTableViewModel(self):
        """
        功能函数
        将搜索数据模型searchSongModel，设置在播放列表tableView上
        """

        # 自定义歌单歌曲动态列表
        # ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
        global Search_Song_List
        # searchSongModel = ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏']
        self.searchSongModel.clear()
        for i in Search_Song_List:
            self.searchSongModel.appendRow([
                QStandardItem(i[0]),
                QStandardItem(i[1]),
                QStandardItem(i[2]),
                QStandardItem(i[3]),
                QStandardItem(i[4]),
                QStandardItem(i[5]),
            ])
        # 编历循环，customSongModel没有数据的话，直接显示空列表
        if self.searchSongModel.rowCount() == 0:
            self.tableView.setModel(self.searchSongModel)
        else:
            # customSongModel有数据的话再遍历单元格显示居中，否则会报错
            for row in range(len(Search_Song_List)):
                for column in range(6):
                    self.searchSongModel.item(row, column).setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
                    self.searchSongModel.item(row, column).setFont(QFont("微软雅黑", 8))
            self.tableView.setModel(self.searchSongModel)
        QApplication.processEvents()
        # 槽与信号，双击最近播放列表播放音乐
        # self.tableView.doubleClicked.connect(self.doubleClickedToPlay)
        pass
        pass

    def localTableViewShow(self):

        """
        槽函数
        单击最近播放按钮，将本地歌曲标签转换为最近播放标签、中间空格不变、添加歌曲按钮可用
        最近播放歌曲列表装载本地歌曲列表内容，为本地歌曲列表
        """

        try:
            self.songView.hide()
            self.tableView.resize(self.songView.width(), self.songView.height())
        except:
            pass
        finally:
            QApplication.processEvents()
            self.tableView.show()
            QApplication.processEvents()

        self.label_12.setText("本地歌曲")
        self.pushButton_12.setText("添加歌曲")
        self.pushButton_12.setEnabled(True)
        self.setLocalTableViewModel()

    def recentTableViewShow(self):

        """
        槽函数
        单击最近播放按钮，将本地歌曲标签转换为最近播放标签、中间空格不变、添加歌曲按钮不可用
        本地歌曲列表装载最近播放歌曲列表内容，为最近播放歌曲列表
        """

        self.label_12.setText("最近播放")
        self.pushButton_12.setText("")
        self.pushButton_12.setEnabled(False)
        self.setRecentTableViewModel()

        try:
            self.songView.hide()
            self.tableView.resize(self.songView.width(), self.songView.height())
        except:
            pass
        finally:
            QApplication.processEvents()
            self.tableView.show()
            QApplication.processEvents()

    def favourTableViewShow(self):

        """
        槽函数
        单击最近播放按钮，将本地歌曲标签转换为我的收藏标签、中间空格不变、添加歌曲按钮不可用
        本地歌曲列表装载收藏的歌曲列表内容，为我的收藏歌曲列表
        """
        try:
            self.songView.hide()
            self.tableView.resize(self.songView.width(), self.songView.height())
        except:
            pass
        finally:
            QApplication.processEvents()
            self.tableView.show()
            QApplication.processEvents()

        self.label_12.setText("我的收藏")
        self.pushButton_12.setText("")
        self.pushButton_12.setEnabled(False)
        self.setFavourTableViewModel()

    def searchTableViewShow(self):

        """
        功能函数
        输入想要搜索的歌曲、歌手或者专辑名称，获取到列表展示
        """

        try:
            self.songView.hide()
            self.tableView.resize(self.songView.width(), self.songView.height())
        except:
            pass
        finally:
            QApplication.processEvents()
            self.tableView.show()
            QApplication.processEvents()

        self.label_12.setText("搜索歌曲")
        self.pushButton_12.setText("")
        self.pushButton_12.setEnabled(False)

    def itemCustomTableViewShow(self):
        try:
            self.songView.hide()
            self.tableView.resize(self.songView.width(), self.songView.height())
        except:
            pass
        finally:
            QApplication.processEvents()
            self.tableView.show()
            QApplication.processEvents()

        self.label_12.setText(self.listwidget_6.item(self.listwidget_6.currentRow()).text())
        self.pushButton_12.setText("")
        self.pushButton_12.setEnabled(False)
        self.setItemCustomTableViewModel()

    def findSongViewShow(self):

        """
        槽函数
        单击发现音乐按钮，出现对应的发现阴音乐展示页面
        """

        try:
            if self.tableView:
                self.tableView.hide()
                self.verticalLayout_4.addWidget(self.songView)
                self.songView.show()
        except:
            self.songView = QWebEngineView(self.centralwidget)
            self.tableView.hide()
            self.verticalLayout_4.addWidget(self.songView)
            self.songView.load(QUrl('https://music.163.com/#/discover'))
            QApplication.processEvents()
            self.songView.show()
            QApplication.processEvents()
        finally:
            self.label_12.setText("发现音乐")
            self.pushButton_12.setText("")
            self.pushButton_12.setEnabled(False)

    def myListWidgetRightContext(self, position):

        """
        槽函数
        点击创建的歌单列表中每一项歌单，出现右击菜单
        """

        popMenu = QMenu()
        popMenu.setStyleSheet(
            ".QMenu {"
                "background: white;"
                "color: black;"
                "font: \'微软雅黑\' 10pt;"
                "width: 90px; height: 80px;"
                "padding: 10px 5px 10px 5px;"
                "text-align: center;"
            "}"
            ".QMenu:item::selected {"
                "background: white;"
                "color: red;"
                "font: \'微软雅黑\' 10pt;"
                "width: 90px; height: 80px;"
                "padding: 10px 5px 10px 5px;"
                "text-align: center;"
            "}"
            )
        downloadAct = QAction(QIcon("./static/downloadAct.svg"), "下载歌单", self.listwidget_6)
        delAct = QAction(QIcon("./static/delAct.svg"), "删除歌单", self.listwidget_6)
        renameAct = QAction(QIcon("./static/renameAct.svg"), '编辑歌单', self.listwidget_6)
        # 查看右键时是否在item上面,如果不在.就不显示右击菜单
        if self.listwidget_6.itemAt(position):
            popMenu.addAction(delAct)
            popMenu.addAction(renameAct)
            popMenu.addAction(downloadAct)
        downloadAct.triggered.connect(DownloadItem)
        renameAct.triggered.connect(RenameItem)
        delAct.triggered.connect(DeleteItem)
        popMenu.exec_(self.listwidget_6.mapToGlobal(position))

    def tableViewRightContext(self, position):

        """
        槽函数
        点击歌曲列表中每一行，出现右击菜单
        """

        popMenu = QMenu()
        popMenu.setStyleSheet(
            ".QMenu {"
                "background: white;"
                "color: black;"
                "font: \'微软雅黑\' 10pt;"
                "width: 90px; height: 100px;"
                "padding: 10px 5px 10px 5px;"
                "text-align: center;"
                "}"
            ".QMenu:item::selected {"
                "background: white;"
                "color: red;"
                "font: \'微软雅黑\' 10pt;"
                "width: 90px; height: 100px;"
                "padding: 10px 5px 10px 5px;"
                "text-align: center;"
                "}"
        )
        delAct = QAction(QIcon("./static/delAct.svg"), "删除歌单", self.tableView)
        renameAct = QAction(QIcon("./static/renameAct.svg"), '编辑歌单', self.tableView)
        downloadAct = QAction(QIcon("./static/downloadAct.svg"), "下载歌单", self.tableView)
        addToCustomSongList = QAction(QIcon("./static/downloadAct.svg"), "添加至歌单", self.tableView)
        # self.tableView.rowAt(position.y())，就是鼠标所在位置的行的索引
        # 如果不等于-1的话，就是tableView中有数据显示的话
        if self.tableView.rowAt(position.y()) != -1:
            popMenu.addAction(delAct)
            popMenu.addAction(renameAct)
            popMenu.addAction(downloadAct)
            popMenu.addAction(addToCustomSongList)
            popMenu.exec_(self.tableView.mapToGlobal(position))
        else:
            pass

    def searchResult(self):

        """将搜索框中输入的文本，进行搜索，并将结果传入到搜索歌曲列表中"""

        global Search_Song_List

        # 获取搜索内容
        self.lineedit_12.search_content = self.lineedit_12.text_list.item(self.lineedit_12.text_list.currentRow()).text()
        # 调用搜索API获取搜索结果
        self.Res = Searcher.search(self.lineedit_12.search_content)
        # searchSongModel = ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏']
        # Search_Song_List =  ['歌曲', '播放按钮', '歌手', '专辑', '时长', '收藏', '歌曲id', '歌手id' , '专辑id']
        # 区分歌手、歌曲和专辑三类搜索内容，分别解析对应的结果
        # 如果搜索到结果的话
        if self.Res != None:
            # 每次搜索，初始化全局搜索歌曲列表
            Search_Song_List = []
            # 先将界面转换为搜索歌曲界面
            self.searchTableViewShow()
            if self.lineedit_12.search_content[:2] == "歌曲":
                for i in self.Res:
                    a = requests.get("http://122.51.226.175:3000/song/url?id=" + str(i['id'])).json()
                    # 如果歌曲code等于200的话，表示其不是vip歌曲
                    if a['code'] == 200:
                        song_name = i['name']
                        song_artist = i['artists'][0]['name']
                        album_name = i['album']['name']
                        duration = int(str(i['duration'])[:3])
                        # 如果歌曲的描述小于10的话，自动添加0
                        if (duration % 60) <= 9:
                            song_duration = str(duration // 60) + ':0' + str(duration % 60)
                        else:
                            song_duration = str(duration // 60) + ':' + str(duration % 60)
                        song_id = i['id']
                        artist_id = i['artists'][0]['id']
                        album_id = i['album']['id']
                        # 存入搜索到的歌曲列表里面
                        Search_Song_List.append([
                            song_name, '', song_artist, album_name, song_duration, False, song_id, artist_id, album_id
                        ])
            elif self.lineedit_12.search_content[:2] == "歌手":
                for i in self.Res:
                    a = requests.get("http://122.51.226.175:3000/song/url?id=" + str(i['id'])).json()
                    # 如果歌曲code等于200的话，表示其不是vip歌曲
                    if a['code'] ==200:
                        # 如果可以查询到对应id的歌曲的话，进行解析存入搜索歌曲列表
                        if a['data'][0]['size'] != 0 and a['data'][0]['br'] != 0:
                            length = int(str(a['data'][0]['size'] / a['data'][0]['br'] * 8)[:3])
                            if length % 60 < 9:
                                lengthMin = str(length // 60) + ':0' + str(length % 60)
                            else:
                                lengthMin = str(length // 60) + ':' + str(length % 60)
                            Search_Song_List.append([
                                i['name'], '', i['ar'][0]['name'], i['al']['name'], lengthMin, False, i['id'], i['ar'][0]['id'],
                                 i['al']['id']
                            ])
            # 将结果设置到tableView
            self.setSearchTableViewModel()
        # 没有搜索到结果的话，就提示信息
        else:
            message = QMessageBox()
            message.setStyleSheet("color: red; background-color: white;")
            message.warning(self.tableView, "提示", "未找到搜索结果！", QMessageBox.Close)

    def signalAction(self):

        """
        所有的信号与槽的集合
        """

        global GlobalPlayer
        # 单价添加歌曲按钮，保存选中文件夹下的歌曲文件
        self.pushButton_12.clicked.connect(self.saveSongDir)
        # 点击别表表格某一行，获取当前行的歌曲信息并显示
        self.tableView.clicked.connect(self.clickGetSongInfo)
        # 双击列表表格某一行，播放歌曲
        self.tableView.doubleClicked.connect(self.doubleClickedToPlay)
        # 全局播放器当前播放的歌曲一改变，就改变显示的歌曲信息
        GlobalPlayer.player.currentMediaChanged.connect(self.changeStatus)
        # 全局播放器当前播放的歌曲一改变，就改变列表表格选中的行
        GlobalPlayer.player.currentMediaChanged.connect(self.tableViewRowSelected)
        # 全局播放器的播放或者暂停状态一改变，就打开或者关闭定时器，控制进度条和播放时间标签的暂停或者运动
        GlobalPlayer.player.stateChanged.connect(self.timerStatus)
        # 全局播放器的播放或者暂停状态一改变，就把当前播放的歌曲写入最近播放列表
        GlobalPlayer.player.stateChanged.connect(self.saveRecentSong)
        # 拖动进度条，可以前进到任意歌曲的播放节点
        self.horizontalSlider.sliderMoved[int].connect(self.sliderMove)
        # 每过1秒钟，播放进度条前进1格
        self.timer.timeout.connect(self.playerTimer)
        # 单击音量调整按钮，出现界面
        self.pushbutton_label_7.clicked.connect(self.volChangeAction)
        # 点击本地歌曲按钮，本地歌曲页面出现
        self.pushButton_3.clicked.connect(self.localTableViewShow)
        # 点击最近播放，出现最近播放的界面
        self.pushButton_4.clicked.connect(self.recentTableViewShow)
        # 点击我的收藏按钮，出现已经收藏的歌曲按钮
        self.pushButton_5.clicked.connect(self.favourTableViewShow)
        # 点击收藏按钮，收藏当前播放的歌曲
        self.pushbutton_label_5.clicked.connect(self.saveFavourSong)
        # 点击发现音乐按钮，出现发现音乐界面
        self.pushButton.clicked.connect(self.findSongViewShow)
        # 右击创建的歌单列表，出现右键菜单
        self.listwidget_6.customContextMenuRequested[QPoint].connect(self.myListWidgetRightContext)
        # 在右击列表中选中的歌曲行，出现对应每首歌的右键菜单
        self.tableView.customContextMenuRequested[QPoint].connect(self.tableViewRightContext)
        # 点击创建的歌单列表，右边会出现对应的歌曲列表
        self.listwidget_6.itemClicked.connect(self.itemCustomTableViewShow)
        # 搜索框图标单击后出现搜索结果
        self.lineedit_12_image.triggered.connect(self.searchResult)
        # 选中下拉输入框内的item项目后，出现搜索结果
        self.lineedit_12.text_list.itemClicked.connect(self.searchResult)


class MyLabelPlayStop(QLabel):

    """自定义的播放暂停标签"""

    def __int__(self, parent=None):
        # 自定义单击信号
        super(MyLabelPlayStop, self).__init__(parent)

    def mousePressEvent(self, event):  # 单击

        """重写鼠标单击事件"""

        global Label_3_Clicked_Flag
        global GlobalPlayer
        if event.buttons() == Qt.LeftButton:  # 左键按下
            if Label_3_Clicked_Flag:
                self.label_3_pix = QPixmap("./static/label_3_stop.svg").scaled(40, 50)
                self.setPixmap(self.label_3_pix)
                Label_3_Clicked_Flag = False
                GlobalPlayer.player.play()
            else:
                self.label_3_pix = QPixmap("./static/label_3_play.svg").scaled(40, 50)
                self.setPixmap(self.label_3_pix)
                Label_3_Clicked_Flag = True
                GlobalPlayer.player.pause()
        elif event.buttons() == Qt.RightButton:  # 右键按下
            print("单击鼠标右键： 自己定义")  # 响应测试语句
        elif event.buttons() == Qt.MidButton:  # 中键按下
            print("单击鼠标中键： 自己定义")  # 响应测试语句
        elif event.buttons() == Qt.LeftButton | Qt.RightButton:  # 左右键同时按下
            print("单击鼠标左右键： 自己定义")  # 响应测试语句
        elif event.buttons() == Qt.LeftButton | Qt.MidButton:  # 左中键同时按下
            print("单击鼠标左中键： 自己定义")  # 响应测试语句
        elif event.buttons() == Qt.MidButton | Qt.RightButton:  # 右中键同时按下
            print("单击鼠标右中键： 自己定义")  # 响应测试语句
        elif event.buttons() == Qt.LeftButton | Qt.MidButton \
                | Qt.RightButton:  # 左中右键同时按下
            print("单击鼠标左中右键： 自己定义")  # 响应测试语句

    def wheelEvent(self, event):

        """重载一下滚轮滚动事件"""

        #        if event.delta() > 0:                                                 # 滚轮上滚,PyQt4
        # This function has been deprecated, use pixelDelta() or angleDelta() instead.
        angle = event.angleDelta() / 8  # 返回QPoint对象，为滚轮转过的数值，单位为1/8度
        angleX = angle.x()  # 水平滚过的距离(此处用不上)
        angleY = angle.y()  # 竖直滚过的距离
        if angleY > 0:
            print("鼠标滚轮上滚： 自己定义")  # 响应测试语句
        else:  # 滚轮下滚
            print("鼠标滚轮下滚： 自己定义")  # 响应测试语句

    def mouseDoubieCiickEvent(self, event):

        """重载一下鼠标双击事件"""

        #        if event.buttons () == Qt.LeftButton:                           # 左键按下
        #            self.setText ("双击鼠标左键的功能: 自己定义")
        print("鼠标双击： 自己定义")

    def mouseReleaseEvent(self, event):

        """重载一下鼠标键释放事件"""

        print("鼠标释放： 自己定义")  # 响应测试语句

    def mouseMoveEvent(self, event):

        """重载一下鼠标移动事件"""

        print("鼠标移动： 自己定义")  # 响应测试语句

    def enterEvent(self, event):

        """重载一下鼠标进入控件事件"""

        pass

    def leaveEvent(self, event):

        """重载一下鼠标离开控件事件"""

        pass


class MyLabelBack(QLabel):

    """自定义后退标签"""

    def __int__(self, parent=None):
        # 自定义单击信号
        super(MyLabelBack, self).__init__(parent)

    def mousePressEvent(self, event):  # 单击

        """重写鼠标单击事件"""

        global GlobalPlayer
        # 左键按下
        if event.buttons() == Qt.LeftButton:
            # 鼠标左键按下，图标变小
            self.label_2_pix = QPixmap("./static/label_2.svg").scaled(27, 27)
            self.setPixmap(self.label_2_pix)
            if GlobalPlayer.playList.mediaCount() == 0:
                pass
            else:
                GlobalPlayer.preSong()
        # 右键按下
        elif event.buttons() == Qt.RightButton:
            print("单击鼠标右键： 自己定义")  # 响应测试语句
        # 中键按下
        elif event.buttons() == Qt.MidButton:
            print("单击鼠标中键： 自己定义")  # 响应测试语句
        # 左右键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.RightButton:
            print("单击鼠标左右键： 自己定义")  # 响应测试语句
        # 左中键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.MidButton:
            print("单击鼠标左中键： 自己定义")  # 响应测试语句
        # 右中键同时按下
        elif event.buttons() == Qt.MidButton | Qt.RightButton:
            print("单击鼠标右中键： 自己定义")  # 响应测试语句
        # 左中右键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.MidButton | Qt.RightButton:
            print("单击鼠标左中右键： 自己定义")  # 响应测试语句

    def mouseReleaseEvent(self, event):

        """重载一下鼠标键释放事件"""

        # 鼠标释放后恢复原来的图标大小
        self.label_2_pix = QPixmap("./static/label_2.svg").scaled(30, 30)
        self.setPixmap(self.label_2_pix)


class MyLabelGo(QLabel):

    """自定义后退标签"""

    def __int__(self, parent=None):
        # 自定义单击信号
        super(MyLabelGo, self).__init__(parent)

    def mousePressEvent(self, event):  # 单击

        """重写鼠标单击事件"""

        global GlobalPlayer
        # 左键按下
        if event.buttons() == Qt.LeftButton:
            # 鼠标左键按下，图标变小
            self.label_4_pix = QPixmap("./static/label_4.svg").scaled(27, 27)
            self.setPixmap(self.label_4_pix)
            if GlobalPlayer.playList.mediaCount() == 0:
                pass
            else:
                GlobalPlayer.nextSong()
        # 右键按下
        elif event.buttons() == Qt.RightButton:
            print("单击鼠标右键： 自己定义")  # 响应测试语句
        # 中键按下
        elif event.buttons() == Qt.MidButton:
            print("单击鼠标中键： 自己定义")  # 响应测试语句
        # 左右键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.RightButton:
            print("单击鼠标左右键： 自己定义")  # 响应测试语句
        # 左中键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.MidButton:
            print("单击鼠标左中键： 自己定义")  # 响应测试语句
        # 右中键同时按下
        elif event.buttons() == Qt.MidButton | Qt.RightButton:
            print("单击鼠标右中键： 自己定义")  # 响应测试语句
        # 左中右键同时按下
        elif event.buttons() == Qt.LeftButton | Qt.MidButton | Qt.RightButton:
            print("单击鼠标左中右键： 自己定义")  # 响应测试语句

    def mouseReleaseEvent(self, event):

        """重载一下鼠标键释放事件"""

        # 鼠标释放后恢复原来的图标大小
        self.label_4_pix = QPixmap("./static/label_4.svg").scaled(30, 30)
        self.setPixmap(self.label_4_pix)


class MyLabel6(QLabel):

    """自定义循环标签"""

    def __int__(self, parent=None):
        # 自定义单击信号
        super(MyLabel6, self).__init__(parent)
        self.setStyleSheet()

    def mousePressEvent(self, event):  # 单击

        """重写鼠标单击事件"""

        global GlobalPlayerL, Label_6_Flag
        # 左键按下
        if event.buttons() == Qt.LeftButton:
            if Label_6_Flag == 3:
                GlobalPlayer.playList.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
                Label_6_Flag = 1
                self.setText("单曲")
            elif Label_6_Flag == 1:
                GlobalPlayer.playList.setPlaybackMode(QMediaPlaylist.Random)
                Label_6_Flag = 4
                self.setText("随机")
            else:
                GlobalPlayer.playList.setPlaybackMode(QMediaPlaylist.Loop)
                Label_6_Flag = 3
                self.setText("循环")


class MyPushButton(QPushButton):

    """自定义按钮"""

    def __int__(self, parent=None):
        # 自定义单击信号
        super(MyPushButton, self).__init__(parent)


class MyTableView(QTableView):

    """自定义的tableView"""

    def __init__(self, parent=None):
        super(MyTableView, self).__init__(parent)
        # 水平方向标签拓展剩下的窗口部分，填满表格
        self.horizontalHeader().setStretchLastSection(True)
        # 水平方向，表格大小按照内容大小进行调整
        # self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 整行选中的方式
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 每次只能选中一行内容
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        # 设置右键菜单
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        # 隐藏水平和垂直方向的表头
        self.horizontalHeader().setVisible(False)
        self.verticalHeader().setVisible(False)
        # 设置表格不可编辑
        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 设置表格行高默认值
        self.verticalHeader().setDefaultSectionSize(30)
        # 设置表格行高不能调整
        self.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        # 去掉单元格的边框
        self.setShowGrid(False)
        # 去掉点击单元格时候出现的虚线，也就是单元格获取焦点之后的虚线策略
        self.setFocusPolicy(Qt.NoFocus)
        # 设置表格奇偶行背景颜色交替
        self.setAlternatingRowColors(True)
        # 列表表格，奇数行偶数行背景色不同样式设置
        self.setStyleSheet(
            "QTableView::item {color : white;}"
            "QTableView::item:alternate:!selected { background-color: rgb(52, 117, 177, 220);}"
            "QTableView::item:!alternate:!selected { background-color: rgb(39, 125, 177, 0);}"
            "QTableView::item:!alternate:selected { color: black; background-color: rgb(127, 127, 127, 200); }"
            "QTableView::item:alternate:selected { color: black; background-color: rgb(127, 127, 127, 200); }"
        )


class MyQSlider(QSlider):
    """自定义的QSlider"""

    def __init__(self, parent=None, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        # 音量大小标签
        label = QLabel(self)
        self.label = label
        label.setText('100')
        label.setStyleSheet('background-color: white; color: black; font: 7.5pt;')
        label.hide()

    def mousePressEvent(self, evt):
        """滑块按下，音量标签状态变化"""

        super().mousePressEvent(evt)
        y = (1 - ((self.value() - self.minimum()) / (self.maximum() - self.minimum()))) * (
                    self.height() - self.label.height())
        x = (self.width() - self.label.width()) / 2
        self.label.move(x, y)
        self.label.show()
        self.label.setText(str(self.value()))

    def mouseMoveEvent(self, evt):
        """滑块移动，音量标签状态变化"""

        super().mouseMoveEvent(evt)
        y = (1 - ((self.value() - self.minimum()) / (self.maximum() - self.minimum()))) * (
                    self.height() - self.label.height())
        x = (self.width() - self.label.width()) / 2
        self.label.move(x, y)
        self.label.setText(str(self.value()))
        self.label.adjustSize()

    def mouseReleaseEvent(self, evt):
        """滑块停止，音量标签状态变化"""

        super().mouseReleaseEvent(evt)
        self.label.hide()


class Ui_VolChange(QWidget):

    """这是点击音量按钮的音量调整界面类"""

    def __init__(self):
        super(Ui_VolChange, self).__init__()
        self.vol_slider = MyQSlider(self)
        self.setContentsMargins(0, 5, 0, 5)
        self.vol_verticalLayout = QVBoxLayout(self)
        self.vol_verticalLayout.addWidget(self.vol_slider)
        # 隐藏窗口的所有按钮
        self.setWindowFlags(Qt.WindowCloseButtonHint)


class MyLineEdit(QLineEdit):

    """带下拉框的文本输入框类（文本下拉列表），输入文字可以搜索内容"""

    def __init__(self, parent, name='lineedit_12', drag=False):

        """
        初始化控件
        :param parent: 控件显示的父对象
        :param size: 输入框控件尺寸
        :param name: 输入框控件名称
        :param drag: 拖放标识位
        :param text_list: 下拉列表对象
        """

        super(MyLineEdit, self).__init__(parent)
        # 输入框名称
        self.setObjectName(name)
        # 设置默认的背景文字
        self.setPlaceholderText("输入歌手或歌曲名")
        # 输入框是否支持拖放
        self.drag_flag = False
        if drag:
            self.setAcceptDrops(True)
            self.setDragEnabled(True)  # 开启可拖放事件
        else:
            self.setAcceptDrops(False)
            self.setDragEnabled(False)  # 关闭可拖放事件
        # 生成下拉列表
        self.text_list = QListWidget(parent)
        self.text_list.setStyleSheet(".QListWidget{background-color: white; font: 8pt;color: black;}"
                                     ".QListWidget::Item{background-color: white; font: 8pt; color: black;}"
                                     ".QListWidget::Item:hover{background-color: white; font: 9pt; color: red;}")
        self.text_list.hide()
        # 搜索输入框内的文字一变化就会出来下拉选项
        self.textChanged.connect(self.on_search_data)

    def on_search_data(self):

        """
        文本变化时的消息响应，搜索下拉框列表里的数据
        """

        # 输入框中文本和List选择文本不一样的时候，才显示下拉框
        cur_text = self.text()
        # 下拉列表移动到搜索输入框所在的位置，并变成对应的大小
        self.text_list.move(self.pos().x() + 10,  self.pos().y() + self.height())
        self.text_list.resize(self.width() - 20, 80)
        self.text_list.raise_()
        a = QListWidgetItem("歌手：" + cur_text)
        b = QListWidgetItem("歌曲：" + cur_text)
        self.text_list.clear()
        self.text_list.addItem(a)
        self.text_list.addItem(b)
        self.text_list.show()
        QApplication.processEvents()

    def focusOutEvent(self, QFocusEvent):

        """搜索框失去焦点后，关闭下拉列表"""

        self.text_list.hide()


"""
# 暂时不用的代码
# # 设置背景的方法，paintEvent和qixmap是两种不同的方法
# class MyWindow(Ui_MainWindow, QWidget):
#     def __init__(self):
#         super(MyWindow, self). __init__()
# 
#     def paintEvent(self, QPaintEvent):
#         MainWindow_painter = QtGui.QPainter(self)
#         MainWindow_painter.drawRect(self.rect())
#         background_image_pix = QtGui.QPixmap("./static/player_background.png")
#         MainWindow_painter.drawPixmap(self.rect(), background_image_pix)
# 
#     def qixmap(self):
#         MainWindow_pale = QtGui.QPalette()
#         background_image_pix = QtGui.QPixmap("./static/player_background.png")
#         background_image_pix.scaled(self.width(), self.height())
#         MainWindow_pale.setBrush(self.backgroundRole(), QtGui.QBrush(background_image_pix))
#         self.setPalette(MainWindow_pale)

# class MyModel(QtSql.QSqlTableModel):
# 
#     # 自定义的model
# 
#     def __init__(self):
#         super(MyModel).__init__()
# 
#     def data(self, index, role=None):
# 
#         # 修改表格文本内容居中显示
# 
#         if role == Qt.TextAlignmentRole:
#             return Qt.AlignCenter
#         return QtSql.QSqlTableModel.data(self, index, role)
"""


if __name__ == "__main__":

    """这是开启高分辨率自适应，只有版本5.6.0以上才支持"""
    # 设置PyQt5版本5.6.0
    v_compare = QVersionNumber(5, 6, 0)
    # 获取当前的PyQt5的版本
    v_current, _ = QVersionNumber.fromString(QT_VERSION_STR)
    # 如果当前的版本大于5.6.0
    if QVersionNumber.compare(v_current, v_compare) >= 0:
        # 开启分辨率自适应，也就是对于1080P以上的，自适应高分辨率
        QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
        app = QApplication(sys.argv)
    else:
        app = QApplication(sys.argv)

    # app = QApplication(sys.argv)
    # 实例化主窗口并显示
    mainWindow = Ui_MainWindow()
    qMainWindow = QMainWindow()
    mainWindow.setupUi(qMainWindow)
    # 实例化登录窗口
    loginWindow = LoginWindow.Ui_Form()
    qLoginWindow = QWidget()
    loginWindow.setupUi(qLoginWindow)
    # 实例化添加歌单窗口
    addMySongListWindow = AddMySongListWindow.Ui_Form()
    qAddMySongListWindow = QWidget()
    addMySongListWindow.setupUi(qAddMySongListWindow)

    # 显示主界面
    qMainWindow.show()

    # 如果列表展示区处于显示状态的话，那就把对应的本地音乐按钮变成红色
    if mainWindow.tableView.isVisible():
        mainWindow.pushButton.clearFocus()
        mainWindow.pushButton_3.setFocus()

    # 槽函数集合
    def addMySongList():

        """
        槽函数
        点击确认按钮，增加一个条自定义歌单，同时清空歌单输入框，并关闭窗口
        """

        global mainWindow, addMySongListWindow, qAddMySongListWindow
        mySongListName = addMySongListWindow.lineEdit.text()
        # 如果输入的自定义歌单名称为空的话
        if mySongListName == "":
            QMessageBox.information(addMySongListWindow.pushButton, "提示信息", "空名称，请重新输入！")
        # 如果输入的自定义歌单名称过长的话
        elif len(mySongListName.encode()) > 18:
            QMessageBox.information(addMySongListWindow.pushButton, "提示信息", "名称不超过12个字符")
        else:
            b = mainWindow.listwidget_6.currentRow()
            print("b", b)
            # 如果点击了右击菜单中的重命名歌单功能的话，就修改
            if addMySongListWindow.Add_List_Flag == True:
                mainWindow.listwidget_6.item(b).setText(mySongListName)
                addMySongListWindow.Add_List_Flag = False
            # 否则就是新增收藏的歌单
            else:
                a = QListWidgetItem(mySongListName)
                a.setIcon(QIcon("./static/listWidgetItem.svg"))
                a.setTextAlignment(Qt.AlignLeft)
                mainWindow.listwidget_6.addItem(a)
        addMySongListWindow.lineEdit.clear()
        qAddMySongListWindow.close()
        QApplication.processEvents()

    # TODO 完善下载功能
    def DownloadItem(self):
        pass

    def RenameItem():

        """
        槽函数：链接主界面中的self.listwidget_6.customContextMenuRequested[QPoint]
        创建歌单界面，右击编辑歌单按钮，编辑当前选中的歌单名称
        """

        addMySongListWindow.Add_List_Flag = True
        curRow = mainWindow.listwidget_6.currentRow()
        item = mainWindow.listwidget_6.item(curRow)
        item.setFlags(item.flags() | Qt.ItemIsEditable)
        addMySongListWindow.lineEdit.setText(item.text())
        qAddMySongListWindow.show()

    # TODO 去除右击空白处有小白点的BUG
    def DeleteItem():

        """
        槽函数：链接主界面中的self.listwidget_6.customContextMenuRequested[QPoint]
        创建歌单界面，右击删除歌单按钮，删除选中的歌单
        """

        mainWindow.listwidget_6.takeItem(mainWindow.listwidget_6.currentRow())
        # 删除一个item后，把左侧的创建歌单的列表清空，重新命名为我的歌单
        mainWindow.label_12.setText("我的歌单")

    # TODO 右击菜单，添加到歌曲列表
    def addToCustomSongList():
        pass

    # 信号与槽函数集合
    # 点击用户登录头像，出现用户登录界面
    mainWindow.pushButton_user.clicked.connect(qLoginWindow.show)
    # 点击创建歌单按钮，出现创建歌单界面
    mainWindow.pushButton_label_9.clicked.connect(qAddMySongListWindow.show)
    # 点击创建歌单界面中的取消按钮，创建歌单界面消失
    addMySongListWindow.pushButton_2.clicked.connect(qAddMySongListWindow.close)
    # 点击创建歌单界面中的确认按钮，增加一条自定义的歌单
    addMySongListWindow.pushButton.clicked.connect(addMySongList)


    sys.exit(app.exec_())
